import io.vertx.core.AbstractVerticle
import io.vertx.core.Vertx
import io.vertx.core.logging.LoggerFactory
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.Proxy

internal interface MyService {
  fun someMethod()
}

internal class MyServiceImpl : MyService {
  override fun someMethod() {
    println("Executing someMethod")
  }
}

internal class LoggingProxy private constructor(private val target: Any) : InvocationHandler {
  @Throws(Throwable::class)
  override fun invoke(proxy: Any, method: Method, args: Array<Any>): Any {
    return try {
      logger.info("Before method execution: {}", method.name)
      val result = method.invoke(target, *args)
      logger.info("After method execution: {}", method.name)
      result
    } catch (e: Exception) {
      logger.error("Error during method execution: {}", method.name, e)
      throw e
    }
  }

  companion object {
    private val logger = LoggerFactory.getLogger(LoggingProxy::class.java)
    fun <T> createProxy(target: Any, interfaceClass: Class<T>?): T {
      return Proxy.newProxyInstance(
        target.javaClass.classLoader,
        target.javaClass.interfaces,
        LoggingProxy(target)
      ) as T
    }
  }
}

class AopLoggingExample : AbstractVerticle() {
  override fun start() {
    val myService: MyService = MyServiceImpl()

    // 创建代理
    val proxiedService = LoggingProxy.createProxy(myService, MyService::class.java)

    // 调用代理对象的方法
    proxiedService.someMethod()
  }

  companion object {
    @JvmStatic
    fun main(args: Array<String>) {
      val vertx = Vertx.vertx()
      vertx.deployVerticle(AopLoggingExample())
    }
  }
}
